#pragma once
#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include "../comm/util.hpp"
#include "../comm/Log.hpp"

namespace ns_compiler
{
    using namespace ns_util;
    using namespace ns_Log;
    class compiler
    {
    public:
        compiler() {}
        ~compiler() {}

        // 提供文件名,进行编译服务
        static bool Compile(const std::string &file_name)
        {
            pid_t pid = fork();
            if (pid < 0)
            {
                LOG(Error) << "创建子进程失败" << "\n";
                return false;
            }
            else if (pid == 0)
            {
                // 子进程
                umask(0);
                int fd = open(Pathutil::Err(file_name).c_str(), O_CREAT | O_WRONLY, 0644);
                if (fd < 0)
                {
                    LOG(Error) << "打开" << "Pathutil::Err(file_name)" << "失败" << "\n";
                    exit(2);
                }

                // 重定向
                dup2(fd, 2);

                //程序替换进行编译
                execlp("g++", "g++", "-o", Pathutil::Exe(file_name).c_str(),Pathutil::Src(file_name).c_str(),"-D","COMPILE_ONLINE","-std=c++11", nullptr);
                LOG(Fatal) << "启动编译器失败，可能是参数不正确" << "\n";
                exit(2);
            }
            waitpid(pid, nullptr, 0);
            if (Fileutil::isExist(Pathutil::Exe(file_name)))
            {
                LOG(Info) << "编译成功" << "\n";
                return true;
            }
            LOG(Error) <<"编译失败，没有形成可执行文件"<< "\n";
            return false;
        }
    };
}